package com.wolfking.jeesite.controller;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.wolfking.jeesite.config.SsoConfig;
import com.wolfking.jeesite.entity.*;
import com.wolfking.jeesite.service.*;
import com.wolfking.jeesite.sign.LoginUser;
import com.wolfking.jeesite.sign.Sign;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 角色的controller
 * <p>
 * 字典的增删查改
 *
 * @author wolfking@赵伟伟
 * @mail zww199009@163.com
 * @创作日期 2017年4月26日下午1:09:59
 * @版权 归wolfking所有
 */
@Slf4j
@Controller
@RequestMapping("/sys/role")
public class RoleController {

    @Autowired
    private DictService dictService;

    @Autowired
    private SsoConfig ssoConfig;

    @Autowired
    private RoleService roleService;

    @Autowired
    private OfficeService officeService;

    @Autowired
    private MenuService menuService;

    @Autowired
    private UserService userService;

    /**
     * 字典的列表页，包括模糊查询
     * <p>
     *
     * @param model
     * @param pageNum
     * @param pageSize
     * @return
     */
    @Sign(code = "sys:role:view")
    @RequestMapping(value = "/list", method = {RequestMethod.GET, RequestMethod.POST})
    public String list(Model model, Role role, @RequestParam(defaultValue = "1") int pageNum,
                       @RequestParam(defaultValue = "20") int pageSize) {
        PageInfo<Role> page = roleService.pageLike(role, pageNum, pageSize);
        List<Dict> dicts = dictService.getByType("sys_data_scope");
        model.addAttribute("page", page);
        Map<String, String> dictMap = Maps.newHashMap();
        for (Dict dict : dicts)
            dictMap.put(dict.getValue(), dict.getLabel());
        model.addAttribute("dictMap", dictMap);
        model.addAttribute("role", role);
        Map<String, String> officeMap = Maps.newHashMap();
        List<Office> offices = officeService.list();
        for (Office office : offices)
            officeMap.put(office.getId() + "", office.getName());
        model.addAttribute("officeMap", officeMap);
        return "sys/role/list";
    }

    /**
     * 验证角色名是否有效
     *
     * @param oldName
     * @param name
     * @return
     */
    @Sign
    @ResponseBody
    @RequestMapping(value = "checkName")
    public String checkName(String oldName, String name) {
        if (name != null && name.equals(oldName)) {
            return "true";
        } else if (name != null) {
            Role role = new Role();
            role.setName(name);
            List<Role> list = roleService.selectExample(role);
            if (CollectionUtils.isEmpty(list))
                return "true";
        }
        return "false";
    }

    /**
     * 验证角色英文名是否有效
     *
     * @param oldEnname
     * @param enname
     * @return
     */
    @Sign
    @ResponseBody
    @RequestMapping(value = "/checkEnname")
    public String checkEnname(@RequestParam String oldEnname, @RequestParam String enname) {
        return checkName(oldEnname, enname);
    }

    @Sign(code = "sys:role:view")
    @RequestMapping(value = "/edit", method = RequestMethod.GET)
    public String editGet(Model model, Role role) {
        if (Objects.nonNull(role.getId()))
            role = roleService.getById(role.getId());
        model.addAttribute("role", role);
        List<Dict> dicts = dictService.getByType("sys_data_scope");
        model.addAttribute("dicts", dicts);
        model.addAttribute("menuList", menuService.list());
        model.addAttribute("officeList", officeService.list());
        Office office = new Office();
        if (Objects.nonNull(role.getOfficeId()))
            office = officeService.getById(role.getOfficeId());
        model.addAttribute("office", office);
        return "sys/role/edit";
    }


    @Sign(code = "sys:role:view")
    @RequestMapping(value = "/copyEdit", method = RequestMethod.GET)
    public String copyEdit(Model model, Role role) {
        String view = editGet(model, role);
        role = (Role) model.getAttribute("role");
        if (Objects.nonNull(role) && Objects.nonNull(role.getId())) {
            role.setName(role.getName() + "-2");
            role.setEnname(role.getEnname() + "-2");
            role.setId(null);
            role.setCreateTime(null);
            role.setUpdateTime(null);
            role.setVersion(0);
        }
        return view;
    }


    @Sign(code = "sys:role:edit")
    @RequestMapping(value = "/edit", method = RequestMethod.POST)
    public String editPost(RedirectAttributes redirectAttributes, Role role) {
        if (Objects.isNull(role.getId())) {
            roleService.save(role);
            redirectAttributes.addFlashAttribute("message", "添加角色成功");
        } else {
            roleService.updateById(role);
            redirectAttributes.addFlashAttribute("message", "修改角色成功");
        }
        return ssoConfig.getRedirectWithPath("/sys/role/list");
    }

    @Sign(code = "sys:role:edit")
    @RequestMapping(value = "/assign", method = RequestMethod.GET)
    public String assignGet(@RequestParam Integer id, Model model) {
        Role role = roleService.getById(id);
        Office office = new Office();
        Map<String, String> dictMap = Maps.newHashMap();
        List<Dict> dicts = dictService.getByType("sys_data_scope");
        for (Dict dict : dicts)
            dictMap.put(dict.getValue(), dict.getLabel());
        if (Objects.nonNull(role.getOfficeId()))
            office = officeService.getById(role.getOfficeId());
        Map<String, String> officeMap = Maps.newHashMap();
        List<Office> offices = officeService.list();
        for (Office o : offices)
            officeMap.put(o.getId() + "", o.getName());
        List<User> userList = userService.getUserByRoleId(id);
        if (userList == null)
            userList = Lists.newArrayList();
        model.addAttribute("role", role);
        model.addAttribute("office", office);
        model.addAttribute("dictMap", dictMap);
        model.addAttribute("userList", userList);
        model.addAttribute("officeMap", officeMap);
        return "sys/role/assign";
    }

    /**
     * 删除角色
     *
     * @param id
     * @return
     */
    @Sign(code = "sys:role:edit")
    @RequestMapping(value = "/delete", method = RequestMethod.GET)
    public String delete(@RequestParam Integer id, RedirectAttributes redirectAttributes) {
        if (id.equals(1)) {
            redirectAttributes.addFlashAttribute("message", "最该管理员角色不能删除");
            redirectAttributes.addFlashAttribute("messageType", "warning");
        } else {
            roleService.deleteById(id);
        }
        return ssoConfig.getRedirectWithPath("/sys/role/list");
    }

    /**
     * 移除角色
     *
     * @param userId
     * @param roleId
     * @param redirectAttributes
     * @param current
     * @return
     */
    @Sign(code = "sys:role:edit")
    @RequestMapping(value = "/outrole", method = RequestMethod.GET)
    public String outrole(@RequestParam Integer userId, @RequestParam Integer roleId,
                          RedirectAttributes redirectAttributes, @LoginUser User current) {
        Role role = roleService.getById(roleId);
        User user = userService.getById(userId);

        if (roleId.equals(1) && userId.equals(1)) {
            redirectAttributes.addFlashAttribute("message",
                    "最该管理员不能删除最高管理员的角色");
            redirectAttributes.addFlashAttribute("messageType", "warning");
        } else if (current.getId().equals(userId)) {
            redirectAttributes.addFlashAttribute("message",
                    "无法从角色【" + role.getName() + "】中移除用户【" + user.getName() + "】自己！");
            redirectAttributes.addFlashAttribute("messageType", "warning");
        } else {
            roleService.outrole(roleId, userId);
            redirectAttributes.addFlashAttribute("message",
                    "用户【" + user.getName() + "】从角色【" + role.getName() + "】中移除成功！");
        }
        return ssoConfig.getRedirectWithPath("/sys/role/assign?id=" + roleId);
    }

    @Sign(code = "sys:role:edit")
    @RequestMapping(value = "/user2role", method = {RequestMethod.POST, RequestMethod.GET})
    public String user2role(Model model, @RequestParam Integer roleId) {
        Role role = roleService.getById(roleId);
        List<User> userList = userService.getUserByRoleId(roleId);
        if (Objects.isNull(userList)) {
            userList = Lists.newArrayList();
        }
        String selectIds = userList.stream().map(User::getId).map(String::valueOf).collect(Collectors.joining(","));
        model.addAttribute("role", role);
        model.addAttribute("userList", userList);
        model.addAttribute("selectIds", selectIds);
        model.addAttribute("officeList", officeService.list());
        return "sys/role/user2role";
    }

    @Sign
    @ResponseBody
    @RequestMapping(value = "/users")
    public List<Map<String, Object>> users(@RequestParam Integer officeId) {
        List<Map<String, Object>> mapList = Lists.newArrayList();
        User user = new User();
        user.setOfficeId(officeId);
        List<User> list = userService.selectExample(user);
        for (User e : list) {
            Map<String, Object> map = Maps.newHashMap();
            map.put("id", e.getId());
            map.put("pId", 0);
            map.put("name", e.getName());
            mapList.add(map);
        }
        return mapList;
    }

    @Sign(code = "sys:role:edit")
    @RequestMapping(value = "/assignrole", method = RequestMethod.POST)
    public String assignRole(Role role, String[] idsArr, RedirectAttributes redirectAttributes) {
        role = roleService.getById(role.getId());
        StringBuilder msg = new StringBuilder();
        int newNum = 0;
        for (String s : idsArr) {
            roleService.assignrole(role.getId(), Integer.parseInt(s));
            User user = userService.getById(Integer.parseInt(s));
            if (null != user) {
                msg.append("<br/>新增用户【").append(user.getName()).append("】到角色【").append(role.getName()).append("】！");
                newNum++;
            }
        }
        redirectAttributes.addFlashAttribute("message", "已成功分配 " + newNum + " 个用户" + msg);
        return ssoConfig.getRedirectWithPath("/sys/role/assign?id=" + role.getId());
    }
}
